﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EasyStep.Data.Entities;
using EasyStep.Attributes;
using WPF.TestEditor.Common;

namespace WPF.TestEditor.Controls
{
    public partial class TestStepEdit : UserControlBase
    {
        private const string constPrefix = "c:";
        public event EventHandler DataChanged;
        public event EventHandler RemoveClicked;
        public event EventHandler AddNewClicked;
        public event EventHandler MoveUp;
        public event EventHandler MoveDown;
        private IEnumerable<EasyStep.Attributes.TestAction> Actions;
        private DynamicACCollection AutoCompleteHelper;
        private int _Position;
        public int Position
        {
            get { return _Position; }
            set
            {
                _Position = value;
                ltrInfo.Text = (_Position + 1).ToString();
            }
        }

        public TestStepEdit(TestStep step, IEnumerable<EasyStep.Attributes.TestAction> actions,DynamicACCollection autoCompleteHelper )
        {
            AutoCompleteHelper = autoCompleteHelper;
            Data = step;
            Actions = actions;
            InitializeComponent();
            txtData.AutoCompleteHelper = autoCompleteHelper;
            txtLocator.AutoCompleteHelper = autoCompleteHelper;
            Loaded += new RoutedEventHandler(TestStepEdit_Loaded);
            txtData.DataChanged += new EventHandler(txtData_DataChanged);
            txtLocator.DataChanged += new EventHandler(txtData_DataChanged);
            
        }

        void txtData_DataChanged(object sender, EventArgs e)
        {
            var editor = sender as TestDataConstantEditor;
            if (editor==txtData)
                Data.Data = txtData.Data;
            else if (editor==txtLocator)
            Data.Locator = txtLocator.Data;
            if (DataChanged!=null) 
                DataChanged(this, null);
        }

        void TestStepEdit_Loaded(object sender, RoutedEventArgs e)
        {
            if (Data == null)
            {
                BindComboBox(cmbMainAction, Actions.Where(a => a.ParentId.Equals(Guid.Empty)), "");
                return;
            }
            var stepLocator = Data.Locator;
            var stepData = Data.Data;
            if (Data.ActionId != Guid.Empty)
            {
                Data.Action = Actions.Where(a => a.Id.Equals(Data.ActionId)).FirstOrDefault();
                Data.ActionId = Data.Action == null ? Guid.Empty : Data.Action.Id;
            }
            if (Data.ActionId == Guid.Empty) Data.Action = null;

            var cparent = BindComboBox(cmbMainAction, Actions.Where(a => a.ParentId.Equals(Guid.Empty)), Data.Action ==null?"":
                Data.Action.Parent == null ? Data.Action.Name: Data.Action.Parent.Name);
            var cparentAction =cparent==null?null: cparent.Tag as TestAction;
            var caction = (cparentAction == null) ? null : BindComboBox(cmbSubAction, Actions.Where(a => a.ParentId.Equals(cparentAction.Id)),Data.Action ==null?"":
                Data.Action.Name);
            

            this.txtLocator.Data = stepLocator;
            this.txtData.Data = stepData;
            ValidateAction(null,null);
        }
        public TestStep Data
        {
            get;
            set;
        }
        protected void BindTextBoxes(TestStep data)
        {
            this.txtData.Visibility = data.Action != null && data.Action.RequireData ? Visibility.Visible : Visibility.Hidden;
            this.txtData.Data = data.Data;
            this.txtLocator.Visibility = data.Action != null && data.Action.RequireLocator ? Visibility.Visible : Visibility.Hidden;
            this.txtLocator.Data = data.Locator;
        }

        private ComboBoxItem BindComboBox(ComboBox cbox, IEnumerable<TestAction> dataSource, string selectedName)
        {
            cbox.Items.Clear();
            if (dataSource == null) return null; ;

            cbox.Items.Add(new ComboBoxItem() { Content = "..." });
            foreach (var item in dataSource)
            {
                var citem = new ComboBoxItem() { Tag = item, Content = item.Name };
                cbox.Items.Add(citem);
            }
            var selectedItem = cbox.Items.OfType<ComboBoxItem>()
                .Where(i => i.Tag as TestAction != null && (i.Tag as TestAction).Name.Equals(selectedName,StringComparison.OrdinalIgnoreCase))
                .FirstOrDefault();
            if (selectedItem != null)
                cbox.SelectedItem = selectedItem;
            return selectedItem;
        }



        private bool ValidateAction(TestAction selParentAction, TestAction selAction)
        {
            selParentAction = selParentAction != null ? selParentAction : GetSelectedAction(cmbMainAction);
            selAction = selAction != null ? selAction : GetSelectedAction(cmbSubAction);
            if (selAction == null) selAction = selParentAction;

            Data.ActionId = selAction == null ? Guid.Empty : selAction.Id;
            Data.Action = selAction;
            DataChanged(this, null);
            return Data.Action != null;
        }


        private TestAction GetSelectedAction(ComboBox cbox)
        {
            var selItem = cbox.SelectedItem as ComboBoxItem;
            if (selItem == null) return null;
            else return selItem.Tag as TestAction;
        }




        private void cmbMainAction_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var curaction = Data.Action;
            var maction = GetSelectedAction(cmbMainAction);
            var saction = GetSelectedAction(cmbSubAction);
            ValidateAction(maction, saction);

            var parentId = maction == null ? Guid.Empty : maction.Id;
            IEnumerable<TestAction> subactions = Actions.Where(a => a.ParentId.Equals(parentId));
            var csaction = BindComboBox(cmbSubAction, subactions, curaction == null ? saction==null?"":saction.Name : curaction.Name);
            cmbSubAction.Visibility = subactions.Count() > 0 ? Visibility.Visible : Visibility.Hidden;
            BindTextBoxes(Data);
        }

        private void cmbSubAction_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ValidateAction(null, null);
            BindTextBoxes(Data);
        }

        private void Add_Click(object sender, RoutedEventArgs e)
        {
            AddNewClicked(this, null);
        }

        private void Remove_Click(object sender, RoutedEventArgs e)
        {
            RemoveClicked(this, null);
        }

        private void Down_Click(object sender, RoutedEventArgs e)
        {
            MoveDown(this, null);
        }

        private void Up_Click(object sender, RoutedEventArgs e)
        {
            MoveUp(this, null);
        }
    }
}
